import { NextRequest, NextResponse } from 'next/server' import { semanticIndexingService } from '@/lib/services/semantic-indexing-service' import { createServerSupabaseClient } from '@/lib/supabase' // Create server-side Supabase client with user session function createSupabaseClient(request: Request) { // Get the authorization header from the request const authHeader = request.headers.get('authorization') return createServerSupabaseClient() } export async function POST( req: NextRequest, { params }: { params: { id: string } } ) { try { const { query, maxResults = 10, similarityThreshold = 0.01 } = await req.json() if (!query) { return NextResponse.json({ error: 'Query is required' }, { status: 400 }) } const bookId = params.id const supabase = createSupabaseClient(req) // Get current user session from auth header const authHeader = req.headers.get('authorization') let user try { if (authHeader) { const { data: { user: authUser }, error: authError } = await supabase.auth.getUser(authHeader.replace('Bearer ', '')) if (!authError) user = authUser } else { const { data: { user: sessionUser }, error: sessionError } = await supabase.auth.getUser() if (!sessionError) user = sessionUser } } catch (e) { // Ignore auth errors } if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // Verify user has access to this book const { data: book } = await supabase .from('books') .select('id') .eq('id', bookId) .eq('user_id', user.id) .single() if (!book) { return NextResponse.json({ error: 'Book not found' }, { status: 404 }) } // Perform semantic search const results = await semanticIndexingService.semanticSearch( bookId, query, { maxResults, similarityThreshold } ) return NextResponse.json({ results }) } catch (error) { console.error('Semantic search error:', error) return NextResponse.json( { error: 'Failed to perform semantic search' }, { status: 500 } ) } } export async function GET( req: NextRequest, { params }: { params: { id: string } } ) { try { const bookId = params.id const supabase = createSupabaseClient(req) // Get current user session from auth header const authHeader = req.headers.get('authorization') let user try { if (authHeader) { const { data: { user: authUser }, error: authError } = await supabase.auth.getUser(authHeader.replace('Bearer ', '')) if (!authError) user = authUser } else { const { data: { user: sessionUser }, error: sessionError } = await supabase.auth.getUser() if (!sessionError) user = sessionUser } } catch (e) { // Ignore auth errors } if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // Verify user has access to this book const { data: book } = await supabase .from('books') .select('id') .eq('id', bookId) .eq('user_id', user.id) .single() if (!book) { return NextResponse.json({ error: 'Book not found' }, { status: 404 }) } // Get indexing status const { data: statusData } = await supabase .from('file_embedding_status') .select(` file_id, status, last_processed_at, error_message, file_system_items!inner(name, type) `) .eq('book_id', bookId) const stats = { totalFiles: 0, pendingFiles: 0, processingFiles: 0, completedFiles: 0, failedFiles: 0, files: statusData || [] } statusData?.forEach((item: any) => { stats.totalFiles++ switch (item.status) { case 'pending': case 'stale': stats.pendingFiles++ break case 'processing': stats.processingFiles++ break case 'completed': stats.completedFiles++ break case 'failed': stats.failedFiles++ break } }) return NextResponse.json({ stats }) } catch (error) { console.error('Get indexing status error:', error) return NextResponse.json( { error: 'Failed to get indexing status' }, { status: 500 } ) } }